/*
 * @Description: 图片压缩
 * @Autor: HuiSir<https://gitee.com/huisir001>
 * @Date: 2025-09-15 10:45:12
 * @LastEditTime: 2025-09-16 09:29:46
 */

/**
 * 图片压缩配置参数
 */
export interface CompressConfig {
	maxWidth?: number; // 最大宽度（可选）
	maxHeight?: number; // 最大高度（可选）
	quality?: number; // 压缩质量 (0-1, 默认0.8)
	outputType?: 'blob' | 'dataURL'; // 输出格式 (默认'blob')
}

/**
 * 图片压缩核心函数
 * @param config 压缩配置对象
 * @returns Promise<CompressResult> 压缩结果
 */
export default async function compressImage(
	file: string | File | Blob,
	config: CompressConfig = {}
): Promise<Blob | string> {
	// 参数校验
	if (typeof file !== 'string' && !(file instanceof File) && !(file instanceof Blob)) {
		throw new Error('Invalid file type. Must be string(URL), File, or Blob.');
	}

	// 参数默认值处理
	const { maxWidth = Infinity, maxHeight = Infinity, quality = 0.8, outputType = 'blob' } = config;

	try {
		// 1. 加载图片
		const img = await createImage(file);

		// 2. 计算缩放尺寸（保持宽高比）
		let { naturalWidth: width, naturalHeight: height } = img;
		if (width > maxWidth || height > maxHeight) {
			const ratio = Math.min(maxWidth / width, maxHeight / height);
			width = Math.floor(width * ratio);
			height = Math.floor(height * ratio);
		}

		// 3. 创建Canvas并绘制
		const canvas = document.createElement('canvas');
		canvas.width = width;
		canvas.height = height;
		const ctx = canvas.getContext('2d')!;
		ctx.drawImage(img, 0, 0, width, height);

		// 4. 根据配置输出结果
		try {
			if (outputType === 'blob') {
				const blob = await new Promise<Blob>((resolve) => {
					canvas.toBlob((blob) => resolve(blob!), 'image/jpeg', quality);
				});
				return blob;
			} else {
				const dataURL = canvas.toDataURL('image/jpeg', quality);
				return dataURL;
			}
		} catch (error) {
			console.error('Image compression failed:', error);
			throw error;
		} finally {
			// 5. 内存清理（关键步骤）
			canvas.remove(); // 释放Canvas内存
			URL.revokeObjectURL(img.src); // 释放图片对象内存
		}
	} catch (error) {
		console.error('Image compression failed:', error);
		throw error;
	}
}

/**
 * 创建图片对象
 */
function createImage(file: string | File | Blob): Promise<HTMLImageElement> {
	return new Promise((resolve, reject) => {
		const img = new Image();
		const url = typeof file === 'string' ? file : URL.createObjectURL(file);

		img.crossOrigin = 'Anonymous';

		img.onload = () => {
			URL.revokeObjectURL(url);
			resolve(img);
		};

		img.onerror = () => {
			URL.revokeObjectURL(url);
			reject(new Error('Image load failed'));
		};

		img.src = url;
	});
}

// 使用示例
// compressImage("https://example.com/large-image.jpg", {
//   maxWidth: 800,
//   maxHeight: 600,
//   quality: 0.7, // 可选
//   outputType: "blob", // 可选 'dataURL'
// })
//   .then((result) => {
//     if (result.type === "blob") {
//       // 处理Blob结果
//       const formData = new FormData();
//       formData.append("image", result.data, "compressed.jpg");
//       console.log("压缩后Blob大小:", result.data.size + " bytes");
//     } else {
//       // 处理Base64结果
//       console.log("Base64数据长度:", result.data.length);
//     }
//   })
//   .catch((error) => console.error("压缩失败:", error));
